# -*- coding: utf-8 -*-
"""
配置管理模块
负责加载和管理所有配置参数
"""

from typing import Any, Dict, Optional
from pathlib import Path
import os

try:
    import yaml
except Exception:
    yaml = None


class Config:
    """配置管理器"""

    def __init__(self, config_dict: Optional[Dict[str, Any]] = None):
        """
        初始化配置

        Args:
            config_dict: 配置字典
        """
        self._config = config_dict or {}
        self._validate()

    def _validate(self) -> None:
        """验证配置的有效性"""
        # 设置默认值
        if "outdir" not in self._config:
            self._config["outdir"] = "outputs"

        # 基础配置验证
        required_fields = ["outdir"]
        for field in required_fields:
            if field not in self._config:
                raise ValueError(f"Missing required config field: {field}")

    def get(self, key: str, default: Any = None) -> Any:
        """
        获取配置值

        Args:
            key: 配置键，支持点号分隔的嵌套键（如 "llm.provider"）
            default: 默认值

        Returns:
            配置值
        """
        keys = key.split(".")
        value = self._config

        for k in keys:
            if isinstance(value, dict) and k in value:
                value = value[k]
            else:
                return default

        return value

    def set(self, key: str, value: Any) -> None:
        """
        设置配置值

        Args:
            key: 配置键
            value: 配置值
        """
        keys = key.split(".")
        config = self._config

        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]

        config[keys[-1]] = value

    def to_dict(self) -> Dict[str, Any]:
        """返回配置的字典副本"""
        return self._config.copy()

    @property
    def provider(self) -> str:
        """LLM Provider"""
        return self.get("provider", "none")

    @property
    def model(self) -> str:
        """LLM Model"""
        return self.get("model", "")

    @property
    def api_base(self) -> str:
        """API Base URL"""
        return self.get("api_base", "")

    @property
    def voice(self) -> str:
        """TTS Voice"""
        return self.get("voice", "zh-CN-XiaoxiaoNeural")

    @property
    def rate(self) -> str:
        """TTS Rate"""
        return self.get("rate", "+0%")

    @property
    def pitch(self) -> str:
        """TTS Pitch"""
        return self.get("pitch", "+0Hz")

    @property
    def resolution(self) -> str:
        """Video Resolution"""
        return self.get("resolution", "1280x720")

    @property
    def fps(self) -> int:
        """Video FPS"""
        return self.get("fps", 30)

    @property
    def outdir(self) -> str:
        """Output Directory"""
        return self.get("outdir", "outputs")

    @property
    def no_manim(self) -> bool:
        """Skip Manim"""
        return self.get("no_manim", False)

    @property
    def overwrite(self) -> bool:
        """Overwrite Output"""
        return self.get("overwrite", False)

    @property
    def embed_subtitles(self) -> bool:
        """Embed Subtitles"""
        return self.get("embed_subtitles", False)

    @property
    def burn_subtitles(self) -> bool:
        """Burn Subtitles"""
        return self.get("burn_subtitles", False)

    @property
    def align_subs(self) -> bool:
        """Align Subtitles"""
        return self.get("align_subs", False)

    @property
    def theme(self) -> str:
        """Theme"""
        return self.get("theme", "dark")

    @property
    def use_llm_manim(self) -> bool:
        """Use LLM for Manim"""
        return self.get("use_llm_manim", False)

    @property
    def use_llm_scenes(self) -> bool:
        """Use LLM for Scenes"""
        return self.get("use_llm_scenes", False)

    @property
    def md_scene_level(self) -> int:
        """Markdown Scene Level"""
        return self.get("md_scene_level", 2)

    @property
    def cache_enabled(self) -> bool:
        """Cache Enabled"""
        return self.get("cache", False)

    @property
    def cache_dir(self) -> str:
        """Cache Directory"""
        return self.get("cache_dir", "")

    def get_api_key(self, provider: str) -> Optional[str]:
        """
        获取API Key

        Args:
            provider: Provider名称

        Returns:
            API Key或None
        """
        # 优先级1: 环境变量
        env_key = f"{provider.upper()}_API_KEY"
        if env_key in os.environ:
            return os.environ[env_key]

        # 优先级2: 配置文件
        api_keys = self.get("api_keys", {})
        if isinstance(api_keys, dict):
            return api_keys.get(provider.lower())

        # 优先级3: 直接字段
        direct_key = self.get(f"{provider.lower()}_api_key")
        if direct_key:
            return direct_key

        return None


def load_config(config_path: Optional[Path] = None) -> Config:
    """
    加载配置文件

    Args:
        config_path: 配置文件路径，None则使用默认路径

    Returns:
        配置对象
    """
    config_dict = {}

    # 加载默认配置
    default_config_path = Path.cwd() / "config.yaml"
    if default_config_path.exists() and yaml is not None:
        try:
            with open(default_config_path, "r", encoding="utf-8") as f:
                config_dict.update(yaml.safe_load(f) or {})
        except Exception:
            pass

    # 加载本地配置（覆盖默认配置）
    local_config_path = Path.cwd() / "config.local.yaml"
    if local_config_path.exists() and yaml is not None:
        try:
            with open(local_config_path, "r", encoding="utf-8") as f:
                local_config = yaml.safe_load(f) or {}
                config_dict.update(local_config)
        except Exception:
            pass

    # 加载指定配置文件
    if config_path and config_path.exists() and yaml is not None:
        try:
            with open(config_path, "r", encoding="utf-8") as f:
                config_dict.update(yaml.safe_load(f) or {})
        except Exception:
            pass

    return Config(config_dict)
